<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"
    />
    <meta name="description" content="Particle system fireworks." />
    <meta name="quarkgis-sandcastle-labels" content="Beginner, Showcases" />
    <title>QuarkGIS Demo</title>
    <script type="text/javascript" src="../Sandcastle-header.js"></script>
    <script
      type="text/javascript"
      src="../../../Build/QuarkGISUnminified/QuarkGIS.js"
      nomodule
    ></script>
    <script type="module" src="../load-quarkgis-es6.js"></script>
  </head>
  <body
    class="sandcastle-loading"
    data-sandcastle-bucket="bucket-requirejs.html"
  >
    <style>
      @import url(../templates/bucket.css);
    </style>
    <div id="quarkgisContainer" class="fullSize"></div>
    <div id="loadingOverlay"><h1>Loading...</h1></div>
    <div id="toolbar"></div>
    <script id="quarkgis_sandcastle_script">
      function startup(QuarkGIS) {
        "use strict";
        //Sandcastle_Begin
        var viewer = new QuarkGIS.Viewer("quarkgisContainer", {
          shouldAnimate: true,
        });

        var scene = viewer.scene;
        scene.debugShowFramesPerSecond = true;

        QuarkGIS.Math.setRandomNumberSeed(315);

        var modelMatrix = QuarkGIS.Transforms.eastNorthUpToFixedFrame(
          QuarkGIS.Cartesian3.fromDegrees(-75.59777, 40.03883)
        );
        var emitterInitialLocation = new QuarkGIS.Cartesian3(0.0, 0.0, 100.0);

        var particleCanvas;

        function getImage() {
          if (!QuarkGIS.defined(particleCanvas)) {
            particleCanvas = document.createElement("canvas");
            particleCanvas.width = 20;
            particleCanvas.height = 20;
            var context2D = particleCanvas.getContext("2d");
            context2D.beginPath();
            context2D.arc(8, 8, 8, 0, QuarkGIS.Math.TWO_PI, true);
            context2D.closePath();
            context2D.fillStyle = "rgb(255, 255, 255)";
            context2D.fill();
          }
          return particleCanvas;
        }

        var minimumExplosionSize = 30.0;
        var maximumExplosionSize = 100.0;
        var particlePixelSize = new QuarkGIS.Cartesian2(7.0, 7.0);
        var burstSize = 400.0;
        var lifetime = 10.0;
        var numberOfFireworks = 20.0;

        var emitterModelMatrixScratch = new QuarkGIS.Matrix4();

        function createFirework(offset, color, bursts) {
          var position = QuarkGIS.Cartesian3.add(
            emitterInitialLocation,
            offset,
            new QuarkGIS.Cartesian3()
          );
          var emitterModelMatrix = QuarkGIS.Matrix4.fromTranslation(
            position,
            emitterModelMatrixScratch
          );
          var particleToWorld = QuarkGIS.Matrix4.multiply(
            modelMatrix,
            emitterModelMatrix,
            new QuarkGIS.Matrix4()
          );
          var worldToParticle = QuarkGIS.Matrix4.inverseTransformation(
            particleToWorld,
            particleToWorld
          );

          var size = QuarkGIS.Math.randomBetween(
            minimumExplosionSize,
            maximumExplosionSize
          );
          var particlePositionScratch = new QuarkGIS.Cartesian3();
          var force = function (particle) {
            var position = QuarkGIS.Matrix4.multiplyByPoint(
              worldToParticle,
              particle.position,
              particlePositionScratch
            );
            if (QuarkGIS.Cartesian3.magnitudeSquared(position) >= size * size) {
              QuarkGIS.Cartesian3.clone(
                QuarkGIS.Cartesian3.ZERO,
                particle.velocity
              );
            }
          };

          var normalSize =
            (size - minimumExplosionSize) /
            (maximumExplosionSize - minimumExplosionSize);
          var minLife = 0.3;
          var maxLife = 1.0;
          var life = normalSize * (maxLife - minLife) + minLife;

          scene.primitives.add(
            new QuarkGIS.ParticleSystem({
              image: getImage(),
              startColor: color,
              endColor: color.withAlpha(0.0),
              particleLife: life,
              speed: 100.0,
              imageSize: particlePixelSize,
              emissionRate: 0,
              emitter: new QuarkGIS.SphereEmitter(0.1),
              bursts: bursts,
              lifetime: lifetime,
              updateCallback: force,
              modelMatrix: modelMatrix,
              emitterModelMatrix: emitterModelMatrix,
            })
          );
        }

        var xMin = -100.0;
        var xMax = 100.0;
        var yMin = -80.0;
        var yMax = 100.0;
        var zMin = -50.0;
        var zMax = 50.0;

        var colorOptions = [
          {
            minimumRed: 0.75,
            green: 0.0,
            minimumBlue: 0.8,
            alpha: 1.0,
          },
          {
            red: 0.0,
            minimumGreen: 0.75,
            minimumBlue: 0.8,
            alpha: 1.0,
          },
          {
            red: 0.0,
            green: 0.0,
            minimumBlue: 0.8,
            alpha: 1.0,
          },
          {
            minimumRed: 0.75,
            minimumGreen: 0.75,
            blue: 0.0,
            alpha: 1.0,
          },
        ];

        for (var i = 0; i < numberOfFireworks; ++i) {
          var x = QuarkGIS.Math.randomBetween(xMin, xMax);
          var y = QuarkGIS.Math.randomBetween(yMin, yMax);
          var z = QuarkGIS.Math.randomBetween(zMin, zMax);
          var offset = new QuarkGIS.Cartesian3(x, y, z);
          var color = QuarkGIS.Color.fromRandom(
            colorOptions[i % colorOptions.length]
          );

          var bursts = [];
          for (var j = 0; j < 3; ++j) {
            bursts.push(
              new QuarkGIS.ParticleBurst({
                time: QuarkGIS.Math.nextRandomNumber() * lifetime,
                minimum: burstSize,
                maximum: burstSize,
              })
            );
          }

          createFirework(offset, color, bursts);
        }

        var camera = viewer.scene.camera;
        var cameraOffset = new QuarkGIS.Cartesian3(-300.0, 0.0, 0.0);
        camera.lookAtTransform(modelMatrix, cameraOffset);
        camera.lookAtTransform(QuarkGIS.Matrix4.IDENTITY);

        var toFireworks = QuarkGIS.Cartesian3.subtract(
          emitterInitialLocation,
          cameraOffset,
          new QuarkGIS.Cartesian3()
        );
        QuarkGIS.Cartesian3.normalize(toFireworks, toFireworks);
        var angle =
          QuarkGIS.Math.PI_OVER_TWO -
          Math.acos(
            QuarkGIS.Cartesian3.dot(toFireworks, QuarkGIS.Cartesian3.UNIT_Z)
          );
        camera.lookUp(angle);
        //Sandcastle_End
        Sandcastle.finishedLoading();
      }
      if (typeof QuarkGIS !== "undefined") {
        window.startupCalled = true;
        startup(QuarkGIS);
      }
    </script>
  </body>
</html>
